import json
import pandas as pd
from django.shortcuts import render
from rest_framework.generics import ListAPIView
from apps.oaauth.models import OADepartment, UserStatusChoices
from apps.oaauth.serializers import DepartmentSerializer
from rest_framework.views import APIView
from .serializers import AddStaffSerializer, ActiveStaffSerializer, StaffUploadSerializer
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import get_user_model
from django.core.mail import send_mail
from django.conf import settings
from utils import aeser
from django.urls import reverse
from oaback.celery import debug_task
from .tasks import send_mail_task
from django.views import View
from django.http.response import JsonResponse
from urllib import parse
from rest_framework import generics
from rest_framework import exceptions
from apps.oaauth.serializers import UserSerializer
from .paginations import StaffListPagination
from rest_framework import viewsets
from rest_framework import mixins
from datetime import datetime
from django.http.response import HttpResponse
from django.db import transaction

OAUser = get_user_model()
aes = aeser.AESCipher(settings.SECRET_KEY)


def send_active_email(request, email):
    token = aes.encrypt(email)
    active_path = reverse("staff:active_staff") + "?" + parse.urlencode({"token": token})
    active_url = request.build_absolute_uri(active_path)
    message = f"请点击链接激活账号： {active_url}"
    subject = f"[OA系统]账号激活"
    # send_mail(f'OA系统账号激活', recipient_list=[email], message=message, from_email=settings.DEFAULT_FROM_EMAIL)
    send_mail_task.delay(email, subject, message)

class Department(ListAPIView):
    queryset = OADepartment.objects.all()
    serializer_class = DepartmentSerializer


class ActiveStaffView(View):
    def get(self, request):
        token = request.GET.get('token')
        response = render(request, 'active.html')
        response.set_cookie('token', token)
        return response

    def post(self, request):
        try:
            token = request.COOKIES.get('token')
            email = aes.decrypt(token)
            serializers = ActiveStaffSerializer(data=request.POST)
            if serializers.is_valid():
                form_email = serializers.validated_data.get('email')
                user = serializers.validated_data.get('user')
                if email != form_email:
                    return JsonResponse({"code": "400", "message": "邮箱错误"})
                user.status = UserStatusChoices.ACTIVED
                user.save()
                return JsonResponse({"code": "200", "message": "验证成功"})
            else:
                detail = list(serializers.errors.values())[0][0]
                return JsonResponse({"code": 400, "message": detail})
        except Exception as e:
            return JsonResponse({"code": 400, "message": "token错误!"})


class StaffViewSet(viewsets.GenericViewSet,
                   mixins.CreateModelMixin,
                   mixins.ListModelMixin,
                   mixins.UpdateModelMixin):
    queryset = OAUser.objects.all()
    pagination_class = StaffListPagination

    def get_serializer_class(self):
        if self.request.method in ['GET', 'PUT']:
            return UserSerializer
        else:
            return AddStaffSerializer

    def get_queryset(self):
        department_id = self.request.query_params.get('department')
        realname = self.request.query_params.get('name')
        date_joined = self.request.query_params.get('time[]')

        queryset = self.queryset
        user = self.request.user
        if user.department.name != "董事会":
            if user.uid != user.department.leader.uid:
                raise exceptions.PermissionDenied()
            else:
                queryset = queryset.filter(department_id=user.department_id)

        else:
            if department_id:
                queryset = queryset.filter(department_id=department_id)
        if realname:
            queryset = queryset.filter(realname__icontains=realname)
        if date_joined:
            try:
                start_date = datetime.strptime(date_joined[0], "%Y-%m-%d")
                end_date = datetime.strptime(date_joined[1], "%Y-%m-%d")
                queryset = queryset.filter(date_joined__range=(start_date, end_date))
            except Exception:
                pass

        return queryset.order_by("-date_joined").all()

    def create(self, request, *arge, **kwargs):
        serializer = AddStaffSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            email = serializer.validated_data['email']
            realname = serializer.validated_data['realname']
            password = serializer.validated_data['password']
            user = OAUser.objects.create_user(email=email, realname=realname, password=password)
            department = request.user.department
            user.department = department
            user.save()

            send_active_email(request,email)
            return Response(status=status.HTTP_200_OK)
        else:
            return Response(data={"detail": list(serializer.errors.values())[0][0]}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return super().update(request, *args, **kwargs)




class StaffDownloadView(APIView):
    def get(self, request):
        pks = request.query_params.get('pks')
        try:
            pks = json.loads(pks)
        except Exception:
            return Response({"detail": "员工参数错误"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            current_user = request.user
            queryset = OAUser.objects.all()
            if current_user.department.name != '董事会':
                if current_user.department.leader_id != current_user.uid:
                    return Response({"detail": "没有权限下载"}, status=status.HTTP_403_FORBIDDEN)
                else:
                    queryset = queryset.filter(department_id=current_user.department_id)
            queryset = queryset.filter(pk__in=pks)
            result = queryset.values("realname", "email", "department__name", 'date_joined', 'status')
            staff_df = pd.DataFrame(list(result))
            staff_df = staff_df.rename(
                columns={"realname": "姓名", "email": "邮箱", "department__name": "部门", 'date_joined': "入职日期",
                         'status': "状态"})
            response = HttpResponse(content_type='application/xlsx')
            response['Content-Disposition'] = "attachment; filename=员工信息.xlsx"
            with pd.ExcelWriter(response) as writer:
                staff_df.to_excel(writer, sheet_name="员工信息")

                worksheet = writer.sheets["员工信息"]

                # ..............ai生成自动调整列宽...............
                for idx, col in enumerate(staff_df.columns):
                    # 计算列内容最大宽度
                    max_len = max(
                        staff_df[col].astype(str).map(len).max(),  # 数据最大宽度
                        len(str(col))  # 列标题宽度
                    ) + 2  # 增加2字符缓冲
                    worksheet.set_column(idx, idx, max_len)

                # 特别设置日期格式（如果date_joined是datetime类型）
                if '入职日期' in staff_df.columns:
                    date_format = writer.book.add_format({'num_format': 'yyyy-mm-dd'})
                    date_col_idx = staff_df.columns.get_loc("入职日期")
                    worksheet.set_column(date_col_idx, date_col_idx, 15, date_format)

                # ......................ai生成自动调整列宽...................

            return response
        except Exception as e:
            print(e)
            return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)


class StaffUploadView(APIView):
    def post(self, request):
        serializer = StaffUploadSerializer(data=request.data)
        if serializer.is_valid():
            file = serializer.validated_data.get('file')
            current_user = request.user
            if current_user.department.name != "董事会" or current_user.department.leader_id != current_user.uid:
                return Response({"detail": "您无权访问！"}, status=status.HTTP_403_FORBIDDEN)
            staff_df = pd.read_excel(file)
            users = []
            for index, row in staff_df.iterrows():
                if current_user.department.name != "董事会":
                    department = current_user.department
                else:
                    try:
                        department = OADepartment.objects.filter(name=row['部门']).first()
                        if not department:
                            return Response( {"detail": f"{row['部门']}部门不存在"}, status=status.HTTP_400_BAD_REQUEST)
                    except Exception as e:
                        print(e)
                        return Response({"detail": "部门列不存在"}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    email = row['邮箱']
                    realname= row['姓名']
                    password = "111111"
                    user = OAUser(email=email,realname=realname,department=department,status=UserStatusChoices.UNACTIVED)
                    user.set_password(password)
                    users.append(user)
                except Exception:
                    return Response({"detail":"请检查文件中的邮箱，姓名，部门名称"}, status=status.HTTP_400_BAD_REQUEST)
            try:
                with transaction.atomic():
                    OAUser.objects.bulk_create(users)
            except Exception:
                return Response({'detail': '员工数据添加失败'},status=status.HTTP_400_BAD_REQUEST)

            for user in users:
                send_active_email(request, user.email)
            return Response()
        else:
            detail = list(serializer.errors.values())[0][0]
            return Response({"detail": detail}, status=status.HTTP_400_BAD_REQUEST)


class TestCeleryView(APIView):
    def get(self, request):
        debug_task.delay()
        return Response({"detail": "成功"})
